﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic;
using System.Text;
using Abp.Linq.Extensions;
using System.Threading.Tasks;
using System.Data.Entity;
using Abp.AutoMapper;
using MyCompanyName.AbpZeroTemplate.Prm.Project.Dto;
using Abp.Application.Services.Dto;
using MyCompanyName.AbpZeroTemplate.Prm.Authorization;
using MyCompanyName.AbpZeroTemplate.Prm.Admin;
using Abp.Domain.Repositories;
using MyCompanyName.AbpZeroTemplate.Gantt;
using System.Dynamic;
using Abp.Runtime.Session;
using MyCompanyName.AbpZeroTemplate.Authorization.Users.Dto;
using MyCompanyName.AbpZeroTemplate.Authorization.Users;
using System.Globalization;

namespace MyCompanyName.AbpZeroTemplate.Prm.Project
{
    public class ProjectAppService : AbpZeroTemplateAppServiceBase, IProjectAppService
    {

        private readonly UserManager userManager;
        private readonly GanttManager gantt;
        private readonly ProjectManager projectManager;
        private readonly OperationLogManager operationLogManager;

        private readonly PermissionService permissionService;

        private readonly IRepository<RdCenter, int> rdCenterRepository;
        private readonly IRepository<Inquiry.Inquiry, int> inquiryRepository;
        private readonly IRepository<Laboratory, int> laboratoryRepository;
        private readonly IRepository<SystemDic, int> sysDicRepository;
        private readonly IRepository<Business, int> businessRepository;
        private readonly IRepository<Product, int> productRepository;
        private readonly IRepository<DocumentType, int> documentTypeRepository;
        private readonly IRepository<PushMessage> pushMessageRepository;
        private readonly IRepository<ProjectPhase> projectPhaseRepository;
        private readonly IRepository<ProjectPhaseItem> projectPhaseItemRepository;
        private readonly IRepository<PhaseInfo> phaseInfoRepository;
        private readonly IRepository<PhaseItem> phaseItemRepository;
        private readonly IRepository<ProjectPhaseHistory> projectPhaseHistoryRepository;
        private readonly IRepository<ProjectFollower> projectFollowerRepository;
        private readonly MailManager mailManagerRepository;
        ///private readonly PermissionService permissionService;

        public ProjectAppService(
            ProjectManager _projectManager,
             UserManager _userManager,
            OperationLogManager _operationLogManager,
            IRepository<RdCenter, int> _rdCenterRepository,
            IRepository<Laboratory, int> _laboratoryRepository,
            IRepository<Business, int> _businessRepository,
            PermissionService _permissionService,
            IRepository<Product, int> _productRepository,
            IRepository<PushMessage> _pushMessageRepository,
            IRepository<ProjectPhase> _projectPhaseRepository,
            IRepository<ProjectPhaseItem> _projectPhaseItemRepository,
            IRepository<PhaseItem> _phaseItemRepository,
            IRepository<PhaseInfo> _phaseInfoRepository,
            IRepository<DocumentType, int> _documentTypeRepository,
            IRepository<ProjectPhaseHistory> _projectPhaseHistoryRepository,
            IRepository<ProjectFollower> _projectFollowerRepository,
            IRepository<Inquiry.Inquiry, int> _inquiryRepository,
            IRepository<SystemDic, int> _sysDicRepository,
             MailManager _mailManagerRepository,
            GanttManager _gantt)
        {
            projectFollowerRepository = _projectFollowerRepository;
            userManager = _userManager;
            //permissionService = _permissionService;
            projectManager = _projectManager;
            projectPhaseHistoryRepository = _projectPhaseHistoryRepository;
            operationLogManager = _operationLogManager;
            rdCenterRepository = _rdCenterRepository;
            laboratoryRepository = _laboratoryRepository;
            businessRepository = _businessRepository;
            permissionService = _permissionService;
            productRepository = _productRepository;
            projectPhaseRepository = _projectPhaseRepository;
            projectPhaseItemRepository = _projectPhaseItemRepository;
            pushMessageRepository = _pushMessageRepository;
            phaseItemRepository = _phaseItemRepository;
            documentTypeRepository = _documentTypeRepository;
            phaseInfoRepository = _phaseInfoRepository;
            gantt = _gantt;
            mailManagerRepository = _mailManagerRepository;
            inquiryRepository = _inquiryRepository;
            sysDicRepository = _sysDicRepository;
        }

        public async Task<List<GetProjectTeamCheckedTreeDto>> GetRoleUserTree(int projectId)
        {
            List<GetProjectTeamCheckedTreeDto> puts = new List<GetProjectTeamCheckedTreeDto>();
            var teams = projectManager.projectTeamRepository.GetAll().Where(x => x.ProjectId == projectId).ToList();
            var roles = teams.GroupBy(x => x.ProjectRoleId).Select(x => x.Key);
            foreach (var roleId in roles)
            {
                var role = await projectManager.projectRoleInfoRepository.GetAsync(roleId);
                var node = new GetProjectTeamCheckedTreeDto()
                {
                    @checked = false,
                    expanded = true,
                    children = new List<GetProjectTeamCheckedTreeDto>(),
                    id = (roleId * -1).ToString(),
                    leaf = false,
                    parentId = "0",
                    text = role.RoleName
                };
                var users = teams.Where(x => x.ProjectRoleId == role.Id).Select(x => x.UserId);
                foreach (var userId in users)
                {
                    var user = UserManager.Users.Where(x => x.Id == userId).SingleOrDefault();
                    var child = new GetProjectTeamCheckedTreeDto()
                    {
                        @checked = false,
                        expanded = true,
                        children = null,
                        id = userId.ToString(),
                        leaf = true,
                        parentId = node.id,
                        text = user.Name
                    };
                    node.children.Add(child);
                }
                puts.Add(node);
            }
            return puts;
        }


        public void CreateMail(Dictionary<string, string> dic, int c, int projectId)
        {
            MailCatelog m = (MailCatelog)c;
            mailManagerRepository.CreateMailRecord(dic, m, projectId);
        }

        public void CreateMail(Dictionary<string, string> dic, int c, string userIds)
        {
            MailCatelog m = (MailCatelog)c;
            List<string> _users = userIds.Split(',').ToList();
            List<long> users = new List<long>(_users.Count);
            foreach (var item in _users)
            {
                users.Add(long.Parse(item));
            }
            mailManagerRepository.CreateProTaskMailRecord("", dic, m, users);
        }

        public PagedResultOutput<GetMailLogOutPut> GetMailLog(GetMailLogInput input)
        {
            List<GetMailLogOutPut> results = new List<GetMailLogOutPut>();

            var p = mailManagerRepository._mailRecordRepository.GetAll();

            if (!string.IsNullOrEmpty(input.StartDate))
            {
                DateTime _dts = DateTime.Parse(input.StartDate);
                p = p.Where(x => x.CreationTime >= _dts);
            }

            if (!string.IsNullOrEmpty(input.EndDate))
            {
                DateTime _dte = DateTime.Parse(input.EndDate).AddDays(1);
                p = p.Where(x => x.CreationTime < _dte);
            }

            if (!string.IsNullOrEmpty(input.IsError))
            {
                if (input.IsError == "1")
                {
                    p = p.Where(x => x.IsSuccess);
                }
                if (input.IsError == "-1")
                {
                    p = p.Where(x => !x.IsSuccess);
                }
            }

            if (!string.IsNullOrEmpty(input.Subject))
            {
                p = p.Where(x => x.Subject.Contains(input.Subject));
            }
            int total = p.Count();

            var _results = p.OrderByDescending(x => x.CreationTime).Skip(input.start).Take(input.limit).ToList();

            foreach (var item in _results)
            {
                results.Add(new GetMailLogOutPut()
                {
                    body = item.Body,
                    createOn = item.CreationTime.ToString("yyyy-MM-dd"),
                    errorMsg = item.ErrorMsg,
                    id = item.Id,
                    isSuccess = item.IsSuccess,
                    isSend = item.IsSend,
                    receiver = item.Receivers,
                    subject = item.Subject
                });
            }
            return new PagedResultOutput<GetMailLogOutPut>(total, results);
        }

        /// <summary>
        /// 到期-需要标注完成的阶段进展
        /// </summary>
        public void GetMailPhaseToClose()
        {
            DateTime dt = DateTime.Now.Date;
            var phaseDef = phaseInfoRepository.GetAll().ToList();
            var phaseItemDef = phaseItemRepository.GetAll().ToList();
            var phaseItems = projectPhaseItemRepository.GetAll().Where(x => !x.IsDeleted && !x.IsFinsh && x.PlanFinishDate < dt).OrderBy(x => x.PlanFinishDate).ToList();

            var phase = projectPhaseRepository.GetAll().Where(x => !x.IsDeleted && !x.IsFinsh && x.PlanFinishDate < dt).OrderBy(x => x.PlanFinishDate).ToList();

            var _proIds = phase.Select(x => x.ProjectId).Distinct().ToList();
            var __proIds = phaseItems.Select(x => x.ProjectId).Distinct().ToList();

            var projectIds = new List<int>();
            projectIds.AddRange(_proIds);
            projectIds.AddRange(__proIds);
            projectIds = projectIds.Distinct().ToList();

            System.Text.StringBuilder sb = new StringBuilder();
            foreach (var projectId in projectIds)
            {
                var p = projectManager.projectRepository.Get(projectId);

                //TODO:如果项目不是在进行中；
                if (p.Status != Status.进行中 && p.Status != Status.完成 && p.Status != Status.终止)
                {
                    continue;
                }

                var _phase = phase.Where(x => x.ProjectId == projectId).ToList();
                var _phaseItems = phaseItems.Where(x => x.ProjectId == projectId).ToList();
                var _phaseIds = _phaseItems.Select(x => x.PhaseId).Distinct().ToList();
                _phaseIds.AddRange(_phase.Select(x => x.PhaseId));
                _phaseIds = _phaseIds.Distinct().ToList();
                sb = new StringBuilder();
                sb.Append(@"<style type='text/css'> 
                                table 
                                { 
                                border-collapse: collapse; 
                                border: none;  
                                } 
                                td 
                                { 
                                border: solid #000 1px; 
                                } 
                                </style> ");
                sb.Append("<table border=1>");
                sb.Append("<tr><td>阶段</td><td>计划完成时间</td></tr>");
                foreach (var _phaseId in _phaseIds)
                {
                    var ___pdef = phaseDef.Where(x => x.Id == _phaseId).FirstOrDefault();
                    string phaseTxt = "";
                    string phaseDate = "";
                    if (___pdef != null)
                    {
                        phaseTxt = ___pdef.Name;
                    }
                    var ___p = _phase.Where(x => x.ProjectId == projectId && x.PhaseId == _phaseId).FirstOrDefault();
                    if (___p != null)
                    {
                        phaseDate = ___p.PlanFinishDate.ToString("yyyy-MM-dd");
                    }
                    sb.Append(string.Format("<tr><td>{0}</td><td>{1}</td></tr>"
                   , phaseTxt, phaseDate));


                    foreach (var item in _phaseItems)
                    {
                        var ___pitemdef = phaseItemDef.Where(x => x.Id == item.PhaseItemId).FirstOrDefault();
                        if (___pitemdef != null)
                        {
                            phaseTxt = ___pitemdef.Name;
                            sb.Append(string.Format("<tr><td>>>{0}</td><td>{1}</td></tr>"
                                                 , phaseTxt, item.PlanFinishDate.ToString("yyyy-MM-dd")));
                        }

                    }
                }
                sb.Append("</table>");

                Dictionary<string, string> dic = new Dictionary<string, string>();
                dic["项目编号"] = p.ProjectNo;
                dic["待完成阶段"] = sb.ToString();
                dic["待完成阶段数"] = (phase.Count + phaseItems.Count).ToString();
                mailManagerRepository.CreateMailRecord(dic, MailCatelog.项目阶段计划完成提醒, projectId);
            }
        }

        /// <summary>
        /// 项目完成后，应该结束的报告提醒邮件
        /// </summary>
        public void GetMailDocToClose()
        {


            List<Status> finishStatus = new List<Status>() { 
            Status.终止,
            Status.完成
            };
            var reportnames = sysDicRepository.GetAll().Where(x => x.DictKey == DictKey.项目必须提交的报告 && x.DisplayName != "").Select(x => x.DisplayName).ToList();

            var finishProIds = projectManager.projectRepository.GetAll().Where(x => !x.IsDeleted && finishStatus.Contains(x.Status)).Select(x => x.Id).ToList();
            var validProIds = projectManager.projectProgressRepository.GetAll().Where(x => !x.IsDeleted && finishProIds.Contains(x.ProjectId) && x.Status == Status.进行中).Select(x => x.ProjectId).Distinct().ToList();
            var weekDocTypes = documentTypeRepository.GetAll().Where(x => !x.IsDeleted && reportnames.Contains(x.RootName + x.ParentName + x.Name)).ToList();

            var weekDocTypesIds = weekDocTypes.Select(x => x.Id).ToList();


            System.Text.StringBuilder sb = new StringBuilder();
            foreach (var projectId in validProIds)
            {
                var p = projectManager.projectRepository.Get(projectId);
                var proDocTypes = projectManager.projectDocTypeRepository.GetAll().Where(x => x.ProjectId == projectId && !x.IsDeleted && weekDocTypesIds.Contains(x.DocTypeId)).ToList();
                var docs = projectManager.projectDocmeutRepository.GetAll().Where(x => !x.IsDeleted && weekDocTypesIds.Contains(x.DocTypeId) && x.ProjectId == projectId).ToList();

                var emptyDocTypes = new List<string>();
                var noVersionDocs = new List<string>();


                foreach (var prodocType in proDocTypes)
                {
                    var _docs = docs.Where(x => x.DocTypeId == prodocType.DocTypeId).ToList();
                    if (_docs.Count == 0)
                    {
                        //---需要提交报告
                        var dtype = weekDocTypes.Where(x => x.Id == prodocType.DocTypeId).FirstOrDefault();
                        emptyDocTypes.Add(string.Format("{0} {1} {2}", dtype.RootName, dtype.ParentName, dtype.Name));
                    }
                    else
                    {
                        //---报告需要定版
                        foreach (var item in _docs)
                        {
                            if ((int)item.VersionNo != item.VersionNo)
                            {
                                noVersionDocs.Add(item.Name);
                            }
                        }
                    }
                }

                if (emptyDocTypes.Count + noVersionDocs.Count == 0)
                {
                    continue;
                }


                sb = new StringBuilder();

                if (emptyDocTypes.Count > 0)
                {
                    sb.Append(string.Format(" 您有{0}份报告需要上交<br>", emptyDocTypes.Count));
                    sb.Append(string.Join("<br/>", emptyDocTypes));
                    sb.Append("<br/><br/><br/>");
                }

                if (noVersionDocs.Count > 0)
                {
                    sb.Append(string.Format(" 您有{0}份报告需要定版<br>", noVersionDocs.Count));
                    sb.Append(string.Join("<br/>", noVersionDocs));
                    sb.Append("<br/><br/><br/>");
                }
                if (sb.Length == 0)
                {
                    continue;//没有需要提交报告的情况
                }

                Dictionary<string, string> dic = new Dictionary<string, string>();
                dic["项目编号"] = p.ProjectNo;
                dic["报告内容"] = sb.ToString();
                mailManagerRepository.CreateMailRecord(dic, MailCatelog.项目报告提交提醒, projectId);
            }
        }

        public List<UserListDto> GetProAppAuditUsers(string projectno)
        {
            List<UserListDto> results = new List<UserListDto>();

            var p = projectManager.projectRepository.GetAll().Where(x => x.ProjectNo.Equals(projectno)).FirstOrDefault();
            if (p == null)
            {
                throw new Abp.UI.UserFriendlyException("系统提示", "没有项目:" + projectno);
            }

            //获取有权限的相关人员。
            var hasPermissionUserIds = permissionService.GetPermissionUsers(p.Id, ProjectFunctions.项目授权);
            var users = userManager.Users.AsQueryable().Where(x => hasPermissionUserIds.Any(t => t == x.Id)).ToList();

            return users.Select(x => new UserListDto()
            {
                Id = x.Id,
                Name = x.Name,
                UserName = x.UserName,
                Surname = x.Surname,
                IsActive = x.IsActive
            }).ToList();

        }

        public Abp.Application.Services.Dto.PagedResultOutput<Dto.ProjectOutPut> GetAll(Dto.GetProjectInPut input)
        {
            long userId = 0;
            if (AbpSession.UserId.HasValue)
            {
                userId = (long)AbpSession.UserId;
            }
            if (input.status == null || input.status.Count == 0)
            {
                input.status = new List<int>() { 
                (int)Status.进行中,
                (int)Status.完成,
                (int)Status.暂停,
                (int)Status.终止,
                (int)Status.准备
                };
            }
            input.dte = input.dte.AddDays(1);
            //permissionService.HasPermission(userId, ProjectFunctions.项目成本编辑);
            var query = projectManager.projectRepository.GetAll()
                .Where(x => x.CreationTime >= input.dts && x.CreationTime < input.dte && input.status.Contains((int)x.Status))
                .WhereIf(!string.IsNullOrEmpty(input.ProjectName), x => x.ProjectName.Contains(input.ProjectName))
                .WhereIf(!string.IsNullOrEmpty(input.ProductNo), x => x.ProductNo.Contains(input.ProductNo))
                .WhereIf(!string.IsNullOrEmpty(input.ProjectNo), x => x.ProjectNo.Contains(input.ProjectNo))
                .ToList()
                .Where(x => permissionService.HasPermission(userId, x.Id, ProjectFunctions.项目查看)).ToList();


            if (input.Fstatus > 0)
            {
                var proIds = projectFollowerRepository.GetAll().Select(x => x.ProjectId).ToList();
                query = query.Where(x => proIds.Contains(x.Id)).ToList();
            }

            if (input.phaseStatus == 0)
            {
                var proIds = query.Select(x => x.Id).ToList();
                var filterProIds = projectPhaseRepository.GetAll().Where(x => !x.IsDeleted && proIds.Contains(x.ProjectId) && input.phase.Contains(x.PhaseId)).Select(x => x.ProjectId).Distinct().ToList();
                query = query.Where(x => filterProIds.Contains(x.Id)).ToList();
            }
            else if (input.phaseStatus > 0)
            {
                var proIds = query.Select(x => x.Id).ToList();
                var filterProIds = projectPhaseRepository.GetAll().Where(x => !x.IsDeleted && proIds.Contains(x.ProjectId) && input.phase.Contains(x.PhaseId) && x.IsFinsh).Select(x => x.ProjectId).Distinct().ToList();
                query = query.Where(x => filterProIds.Contains(x.Id)).ToList();

            }


            var projectCount = query.Count();
            var projects = query.OrderBy(input.Sorting)
                .Skip(input.SkipCount).Take(input.MaxResultCount);
            //.Skip(input.SkipCount).Take(input.MaxResultCount)
            var projectListDtos = projects.MapTo<List<ProjectOutPut>>();

            //todo:增加-客户权限；
            bool permissionToViewCustomer = permissionService.HasSysPermission(userId, ProjectFunctions.客户查看);
            if (!permissionToViewCustomer)
            {
                foreach (var item in projectListDtos)
                {
                    item.Customer = "******";
                }
            }


            return new PagedResultOutput<ProjectOutPut>(
                projectCount,
                projectListDtos
                );
        }

        public void GetMailTask()
        {
            string mail_account = System.Configuration.ConfigurationManager.AppSettings["mail_account"];
            string mail_pwd = System.Configuration.ConfigurationManager.AppSettings["mail_pwd"];
            string mail_group = System.Configuration.ConfigurationManager.AppSettings["mail_group"];
            string mail_server = System.Configuration.ConfigurationManager.AppSettings["mail_server"];
            string mail_email = System.Configuration.ConfigurationManager.AppSettings["mail_email"];
            string mail_accountdisplay = System.Configuration.ConfigurationManager.AppSettings["mail_accountdisplay"];
            mailManagerRepository.SendMail(mail_server, mail_account, mail_pwd, mail_group, mail_email, mail_accountdisplay);
            return;
        }


        /// <summary>
        /// 创建项目
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task CreateProject(CreateProjectInPut input)
        {
            //var projectNoCount = projectManager.projectRepository.GetAll().Where(x => x.ProjectNo == input.ProjectNo).Count();
            //if (projectNoCount > 0)
            //{
            //    throw new Abp.UI.UserFriendlyException("系统提示", "项目号重复:" + input.ProjectNo);
            //}
            var projectNameCount = projectManager.projectRepository.GetAll().Where(x => x.ProjectName == input.ProjectName).Count();
            if (projectNameCount > 0)
            {
                throw new Abp.UI.UserFriendlyException("系统提示", "项目名称重复:" + input.ProjectName);
            }
            var model = input.MapTo<ProjectInfo>();
            model.UsedMemberQuan = true;
            model.PlanStartDate = DateTime.Now;
            model.ActualStartDate = DateTime.Now;
            model.ActualEndDate = DateTime.Now;
            model.Status = Status.准备;
            model.TeamCommentStatus = CommentStatus.草稿;
            model.PrmCommentStatus = CommentStatus.草稿;

            var projectCount = projectManager.projectRepository.GetAll().Where(x => x.CreationTime.Year == DateTime.Now.Year).Count();
            model.ProjectNo = input.ProductNo + DateTime.Now.Year + projectCount.ToString().PadLeft(3, '0');


            var bus = new Business();
            if (input.BusinessId > 0) { bus = businessRepository.Get(input.BusinessId); }
            var rdCenter = new RdCenter();
            if (input.RdCenterId > 0) { rdCenter = rdCenterRepository.Get(input.RdCenterId); }
            var lab = new Laboratory();
            if (input.LaboratoryId > 0) { lab = laboratoryRepository.Get(input.LaboratoryId); }
            model.Business = bus.Name;
            model.RdCenter = rdCenter.Name;
            model.Laboratory = lab.Name;

            model.PM = UserManager.Users.Where(x => x.Id == model.PMId).SingleOrDefault().Name;

            var id = await projectManager.projectRepository.InsertAndGetIdAsync(model);

            projectManager.projectTeamRepository.Insert(new ProjectTeam()
            {
                ProjectRoleId = ProjectConst.PM,
                ProjectId = id,
                UserId = model.PMId,
                EndTime = DateTime.Now.AddYears(10),
                StartTime = DateTime.Now
            });

            if (input.PhaseSelect.Count > 0)
            {
                foreach (var item in input.PhaseSelect)
                {
                    if (item > 0)
                    {
                        var pItem = phaseItemRepository.Get(item);
                        await projectPhaseItemRepository.InsertAsync(new ProjectPhaseItem() { IsFinsh = false, PhaseId = pItem.PhaseId, ProjectId = id, Indexno = pItem.Indexno, PhaseItemId = item, PlanFinishDate = model.PlanEndDate, Note = "" });
                    }
                    else
                    {
                        var phaseId = item * -1;
                        var phase = phaseInfoRepository.Get(phaseId);
                        await projectPhaseRepository.InsertAsync(new ProjectPhase() { IsFinsh = false, Indexno = phase.Indexno, Note = "", PhaseId = phaseId, PlanFinishDate = model.PlanEndDate, ProjectId = id });
                    }
                }
            }
            InitGantt(id);
            UpdateInquiryNo(input.Customer, input.ProductNo);
            await operationLogManager.Create(id, "项目创建", HostOperation.项目, Newtonsoft.Json.JsonConvert.SerializeObject(input));


            var user = UserManager.Users.Where(x => x.Id == AbpSession.UserId.Value).FirstOrDefault();
            Dictionary<string, string> dic = new Dictionary<string, string>();
            dic["项目名称"] = input.ProjectName;
            dic["项目编号"] = input.ProjectNo;
            dic["产品号"] = input.ProductNo;
            dic["操作时间"] = DateTime.Now.ToString("yyyy-MM-dd");
            dic["操作人"] = user.Name;
            dic["项目经理"] = UserManager.Users.Where(x => x.Id == input.PMId).SingleOrDefault().Name;
            mailManagerRepository.CreateMailRecord(dic, MailCatelog.新增项目通知, id);
        }


        public void InitGantt(int projectId)
        {
            gantt.setOption("revision", "1", projectId);
            gantt.setOption("projectCalendar", "1", projectId);
            gantt.InitTask(new MyCompanyName.AbpZeroTemplate.Gantt.TaskInfo()
            {
                ProjectId = projectId,
                parentId = null,
                Name = "New Task",
                Guid = Guid.NewGuid(),
                StartDate = DateTime.Now,
                EndDate = DateTime.Now.AddDays(10),
                Duration = 10,
                DurationUnit = "d",
                PercentDone = 0,
                index = 0,
                expanded = false,
                ManuallyScheduled = false,
                Draggable = true,
                Resizable = true,
                Rollup = false,
                ShowInTimeline = false,
                PhantomId = "Gnt.examples.advanced.model.Task-1"
            });
            gantt._calendarRepository.Insert(new MyCompanyName.AbpZeroTemplate.Gantt.Calendar()
            {
                ProjectId = projectId,
                Name = "General",
                DaysPerWeek = 7,
                DaysPerMonth = 30,
                HoursPerDay = 24,
                WeekendFirstDay = 6,
                WeekendsAreWorkdaysRaw = 0,
                WeekendSecondDay = 0,
                DefaultAvailability = new List<string>() { "00:00-24:00" }
            });
        }

        /// <summary>
        /// 编辑项目成本
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task EditCost(EditCostInput input)
        {
            var project = await projectManager.projectRepository.GetAsync(input.Id);
            project.ActualCost = input.ActualCost;
            project.ActualWorkCost = input.ActualWorkCost;
            project.TargetWorkCost = input.TargetWorkCost;
            project.ActualOutPut = input.ActualOutPut;
            project.ActualMaterialCost = input.ActualMaterialCost;
            project.TargetCost = input.TargetCost;
            project.TargetOutPut = input.TargetOutPut;
            project.TargetMaterialCost = input.TargetMaterialCost;
            await operationLogManager.Create(input.Id, "项目成本编辑", HostOperation.项目, Newtonsoft.Json.JsonConvert.SerializeObject(input));
        }

        /// <summary>
        /// 根据ID获取项目
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ProjectOutPut> Get(int id)
        {
            var userId = (long)AbpSession.UserId;
            var project = await projectManager.projectRepository.GetAsync(id);
            bool permissionToViewCustomer = permissionService.HasSysPermission(userId, ProjectFunctions.客户查看);

            var model = project.MapTo<ProjectOutPut>();
            double planProgress = 0;
            int totalDays = (project.PlanEndDate.Date - project.PlanStartDate.Date).Days + 1;
            int doingDays = DateTime.Now.Date >= project.PlanStartDate ? (DateTime.Now.Date - project.PlanStartDate.Date).Days + 1 : 0;
            if (doingDays > totalDays)
            { doingDays = totalDays; }
            planProgress = doingDays * 1.0 / totalDays;

            model.PlanProgress = planProgress < 0 ? 0 : planProgress;

            string sTime = "----";
            string eTime = "----";
            if (project.ProjectProgress.Count() > 0)
            {
                var firstProgress = project.ProjectProgress.Where(x => x.Status == Status.进行中).OrderBy(x => x.Id).FirstOrDefault();
                var lastProgress = project.ProjectProgress.Where(x => x.Status == Status.进行中 || x.Status == Status.完成).OrderByDescending(x => x.Id).FirstOrDefault();

                if (firstProgress != null)
                {
                    decimal actualProgress = 0;
                    if ((decimal)(lastProgress.ActualEndTime - firstProgress.ReportTime).Days != 0)
                    {
                        actualProgress = (decimal)(DateTime.Now - firstProgress.ReportTime).Days / (decimal)(lastProgress.ActualEndTime - firstProgress.ReportTime).Days;
                    }
                    model.ActualProgress = actualProgress < 0 ? 0 : actualProgress;
                    sTime = firstProgress.ReportTime.ToString("yyyy-MM-dd");
                    eTime = lastProgress.ActualEndTime.ToString("yyyy-MM-dd");
                }
            }
            model.ActualEndDate = eTime;
            model.ActualStartDate = sTime;

            var phaseIds = projectPhaseRepository.GetAll().Where(x => !x.IsDeleted && x.ProjectId == id).Select(m => m.PhaseId).ToList();
            var phase = phaseInfoRepository.GetAll().Where(x => phaseIds.Contains(x.Id)).OrderBy(x => x.Indexno).Select(x => x.Name).ToList();
            model.PhaseIds = string.Join(",", phaseIds);
            model.PhaseText = string.Join(",", phase);

            if (!permissionToViewCustomer)
            {
                model.Customer = "******";
            }
            return model;
        }

        public string GetProNo(int id)
        {
            return projectManager.projectRepository.Get(id).ProjectNo;
        }

        /// <summary>
        /// 设置项目进展
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task CreateProjectProgress(CreateProjectProgressInput input)
        {
            var model = input.MapTo<ProjectProgress>();
            await projectManager.SetProjectProgress(model);

            var project = projectManager.projectRepository.Get(input.ProjectId);


            #region 项目状态变更
            var user = UserManager.Users.Where(x => x.Id == AbpSession.UserId.Value).FirstOrDefault();
            Dictionary<string, string> dic = new Dictionary<string, string>();
            dic["项目名称"] = project.ProjectName;
            dic["项目编号"] = project.ProjectNo;
            dic["产品号"] = project.ProductNo;
            dic["操作时间"] = DateTime.Now.ToString("yyyy-MM-dd");
            dic["操作人"] = user.Name;
            dic["之前状态"] = project.Status.ToString();
            dic["之前进度"] = project.ProgressStatus.ToString();
            dic["之前预期完成"] = project.ActualEndDate.ToString("yyyy-MM-dd");

            dic["当前状态"] = input.Status.ToString();
            dic["当前进度"] = input.ProgressStatus.ToString();
            dic["当前预期完成"] = input.ActualEndTime.ToString("yyyy-MM-dd");
            dic["描述"] = input.Note;
            #endregion


            var _lastprogress = await projectManager.projectProgressRepository.GetAll().
                Where(x => x.ProjectId == input.ProjectId).
                OrderByDescending(x => x.ReportTime).FirstOrDefaultAsync();


            project.ActualEndDate = _lastprogress.ActualEndTime;
            project.ProgressStatus = input.ProgressStatus;
            project.Status = _lastprogress.Status;
            project.ReportWeek = _lastprogress.ReportWeek;
            projectManager.projectRepository.Update(project);
            await operationLogManager.Create(input.ProjectId, "项目状态编辑", HostOperation.项目, Newtonsoft.Json.JsonConvert.SerializeObject(input));



            #region 项目状态变更
            mailManagerRepository.CreateMailRecord(dic, MailCatelog.项目状态变更, input.ProjectId);
            #endregion

        }


        public async Task DelProgress(int id)
        {
            var progress = await projectManager.projectProgressRepository.GetAsync(id);
            var _lastprogress = await projectManager.projectProgressRepository.GetAll().Where(x => x.ProjectId == progress.ProjectId && x.Id != id).OrderByDescending(x => x.ReportTime).FirstOrDefaultAsync();
            if (_lastprogress != null)
            {
                var project = await projectManager.projectRepository.GetAsync(progress.ProjectId);
                project.ActualEndDate = _lastprogress.ActualEndTime;
                project.Status = _lastprogress.Status;
                project.ReportWeek = _lastprogress.ReportWeek;
            }


            await projectManager.projectProgressRepository.DeleteAsync(id);
        }

        /// <summary>
        /// 编辑项目信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task EditProject(EditProjectInPut input)
        {
            var userId = (long)AbpSession.UserId;
            var project = await projectManager.projectRepository.GetAsync(input.Id);
            bool permissionToViewCustomer = permissionService.HasSysPermission(userId, ProjectFunctions.客户查看);

            var bus = new Business();
            if (input.BusinessId > 0)
            {
                bus = businessRepository.Get(input.BusinessId);
            }
            var rdCenter = new RdCenter();
            if (input.RdCenterId > 0)
            {
                rdCenter = rdCenterRepository.Get(input.RdCenterId);
            }
            var lab = new Laboratory();
            if (input.LaboratoryId > 0)
            {
                lab = laboratoryRepository.Get(input.LaboratoryId);
            }
            if (input.PMId > 0)
            {
                project.PMId = input.PMId;
                project.PM = UserManager.Users.Where(x => x.Id == input.PMId).SingleOrDefault().Name;
            }
            //project.ProjectNo = input.ProjectNo;
            project.ProductNo = input.ProductNo;

            if (permissionToViewCustomer)
            {
                project.Customer = input.Customer;
            }

            project.BusinessId = input.BusinessId;
            project.Business = bus.Name;
            project.RdCenter = rdCenter.Name;
            project.Laboratory = lab.Name;
            project.RdCenterId = input.RdCenterId;
            project.QualityStandard = input.QualityStandard;
            project.ProjectNature = input.ProjectNature;
            project.TargetWorkCost = input.TargetWorkCost;
            project.TargetOutPut = input.TargetOutPut;
            project.PlanStartDate = input.PlanStartDate;
            project.ProjectName = input.ProjectName;
            project.Address = input.Address;
            project.CustomeCode = input.CustomeCode;
            project.LaboratoryId = input.LaboratoryId;
            project.TaskType = input.TaskType;
            project.TargetEndDate = input.TargetEndDate;
            project.TargetCost = input.TargetCost;
            project.TargetMaterialCost = input.TargetMaterialCost;
            project.PlanEndDate = input.PlanEndDate;
            project.Remark = input.Remark;
            project.ReportWeek = input.ReportWeek;

            if (input.PhaseIds != null && input.PhaseIds.Count > 0)
            {
                //List<int> phases = input.PhaseIds.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => Convert.ToInt32(x)).ToList();

                var phases = projectPhaseRepository.GetAll().Where(x => !x.IsDeleted && x.ProjectId == input.Id).Select(x => x.PhaseId).ToList();

                var phaseIds = input.PhaseIds.Where(x => x < 0).Select(x => x * -1);
                var adds = phaseIds.Where(x => !phases.Contains(x));
                var dels = phases.Where(x => !phaseIds.Contains(x));

                foreach (var item in adds)
                {
                    var phase = phaseInfoRepository.Get(item);
                    await projectPhaseRepository.InsertAsync(new ProjectPhase()
                    {
                        IsFinsh = false,
                        Indexno = phase.Indexno,
                        PhaseId = item,
                        ProjectId = input.Id,
                        PlanFinishDate = project.PlanEndDate,
                        Note = ""
                    });
                }

                var items = projectPhaseItemRepository.GetAll().Where(x => x.ProjectId == input.Id).Select(x => x.PhaseItemId).ToList();
                var phaseItemIds = input.PhaseIds.Where(x => x > 0);
                var addItemss = phaseItemIds.Where(x => !items.Contains(x)).ToList();
                var delItems = items.Where(x => !phaseItemIds.Contains(x)).ToList();

                foreach (var item in addItemss)
                {
                    var phaseItem = phaseItemRepository.Get(item);
                    await projectPhaseItemRepository.InsertAsync(new ProjectPhaseItem()
                    {
                        IsFinsh = false,
                        Indexno = phaseItem.Indexno,
                        PhaseId = phaseItem.PhaseId,
                        PhaseItemId = item,
                        ProjectId = input.Id,
                        PlanFinishDate = project.PlanEndDate,
                        Note = ""
                    });
                }
                await projectPhaseRepository.DeleteAsync(x => dels.Contains(x.PhaseId));
                await projectPhaseItemRepository.DeleteAsync(x => delItems.Contains(x.PhaseItemId));
            }

            UpdateInquiryNo(input.Customer, input.ProductNo);

            await operationLogManager.Create(input.Id, "项目编辑", HostOperation.项目, Newtonsoft.Json.JsonConvert.SerializeObject(input));
        }
        /// <summary>
        /// 更新-询盘相关的九洲编号
        /// </summary>
        private void UpdateInquiryNo(string customer, string No)
        {
            if (!string.IsNullOrWhiteSpace(No))
            {
                var subIds = productRepository.GetAll().Where(x => x.Code == No).Select(x => x.SubstanceId).Distinct().ToList();
                var inquirys = inquiryRepository.GetAll().Where(x => subIds.Contains(x.SubId) && x.CustomerName == customer).ToList();
                foreach (var item in inquirys)
                {
                    item.InquiryNo = No;
                    inquiryRepository.Update(item);
                }
            }

        }

        public void ResetQuriyNo()
        {
            var inquriys = inquiryRepository.GetAll().ToList();
            var projects = projectManager.projectRepository.GetAll().ToList();
            foreach (var item in inquriys)
            {
                var codes = productRepository.GetAll().Where(x => x.SubstanceId == item.SubId).Select(x => x.Code).ToList();
                var _codes = projects.Where(x => x.Customer == item.CustomerName && codes.Contains(x.ProductNo)).Select(x => x.ProductNo).ToList();
                if (_codes.Count > 0)
                {
                    item.InquiryNo = _codes[0];
                }
                else
                { item.InquiryNo = ""; }
            }
        }


        public async Task SetProjectTeam(CreateProjectTeamInPut input)
        {
            if (input.RoleId == ProjectConst.PM && input.Users.Count > 1)
            {
                throw new Abp.UI.UserFriendlyException("系统提示", "项目经理只能有一个");
            }
            if (input.RoleId == ProjectConst.PM && input.Users != null)
            {
                var p = projectManager.projectRepository.Get(input.ProjectId);
                var userId = input.Users[0];
                var user = userManager.Users.Where(x => x.Id == userId).SingleOrDefault();
                p.PM = user.Name;
                p.PMId = input.Users[0];

            }
            await projectManager.SetProjectTeam(input.ProjectId, input.RoleId, input.Users);

            await operationLogManager.Create(input.ProjectId, "项目成员编辑", HostOperation.项目, Newtonsoft.Json.JsonConvert.SerializeObject(input));
        }



        /// <summary>
        /// 项目团队
        /// </summary>
        /// <param name="projectId"></param>
        /// <returns></returns>
        public List<ProjectTeamOutPut> GetProjectTeam(int projectId)
        {
            if (projectId == 0)
                throw new Abp.UI.UserFriendlyException("系统提示", "projectId不能为零");

            List<ProjectTeamOutPut> outPuts = new List<ProjectTeamOutPut>();
            var project = projectManager.projectRepository.GetAll().Include("ProjectTeam").Where(x => x.Id == projectId).SingleOrDefault();
            var groups = project.ProjectTeam.GroupBy(x => x.ProjectRoleId).Select(x => x.Key);
            foreach (var roleId in groups)
            {
                var role = projectManager.projectRoleInfoRepository.GetAll().Where(x => x.Id == roleId).FirstOrDefault();
                if (role != null)
                {
                    var teams = project.ProjectTeam.Where(x => x.ProjectRoleId == roleId).Select(m => new ProjectTeamItems(m.Id, m.UserId, m.StartTime.ToString("yyyy-MM-dd"), m.EndTime.ToString("yyyy-MM-dd"))).ToList();

                    foreach (var item in teams)
                    {
                        var u = userManager.Users.Where(x => x.Id == item.userId).FirstOrDefault();
                        item.userName = u.Name;
                    }

                    outPuts.Add(new ProjectTeamOutPut()
                    {
                        RoleName = role.RoleName,
                        RoleSortor = role.Sortfactor,
                        Teams = teams
                    });
                }

            }
            return outPuts.OrderBy(x => x.RoleSortor).ToList();
        }


        /// <summary>
        /// 可能需要写周报的项目组员
        /// </summary>
        /// <param name="projectId"></param>
        /// <returns></returns>
        public List<ProjectWeekTeam> GetWeekProjectTeam(int projectId, DateTime dts)
        {
            if (projectId == 0)
                throw new Abp.UI.UserFriendlyException("系统提示", "projectId不能为零");
            List<ProjectWeekTeam> outPuts = new List<ProjectWeekTeam>();
            _GetProjectWeekTeam(outPuts, new List<int>() { projectId }, dts);
            return outPuts;
        }

        public List<ProjectWeekTeam> GetWeekProjectTeam()
        {
            List<ProjectWeekTeam> outPuts = new List<ProjectWeekTeam>();
            List<Status> doingProject = new List<Status>() { 
            Status.进行中,
             Status.暂停
            };
            var projects = projectManager.projectRepository.GetAll().Where(x => !x.IsDeleted && doingProject.Contains(x.Status)).ToList();
            DateTime dts = DateTime.Now;
            if (projects.Count > 0)
            {
                dts = projects.Select(x => x.PlanStartDate).Min();
            }
            _GetProjectWeekTeam(outPuts, projects.Select(x => x.Id).ToList(), dts);
            return outPuts;

        }

        private void _GetProjectWeekTeam(List<ProjectWeekTeam> _outPuts, List<int> projectIds, DateTime dts)
        {
            List<ProjectWeekTeam> outPuts = new List<ProjectWeekTeam>();
            List<ProjectWeek> projectWorkingWeek = new List<ProjectWeek>();

            _GetProjectDoingWeek(projectIds, projectWorkingWeek);


            List<NoneWorkDays> noneworkdays = GetNoneWorkDays();

            foreach (var item in projectWorkingWeek)
            {


                DateTime dtMonday = DateHelper.GetMondayDate(item.dts);

                do
                {
                    if (outPuts.Any(x => x.dts <= item.dts && x.dte > item.dte))
                    {
                        var _outItem = outPuts.Where(x => x.dts <= item.dts && x.dte > item.dte).FirstOrDefault();
                        dtMonday = _outItem.dte;
                    }
                    else
                    {
                        var _outItem = new ProjectWeekTeam()
                        {
                            dte = item.reportWeek > 1 ? dtMonday.AddDays(14) : dtMonday.AddDays(7),
                            dts = dtMonday,
                            FileName = "",
                            FileUrl = "",
                            //week = weekDic[dtMonday],
                            year = 0,
                            proId = item.projectId
                        };
                        outPuts.Add(_outItem);

                        dtMonday = _outItem.dte;
                    }


                } while (dtMonday < item.dte);

            }

            foreach (var _outItem in outPuts)
            {
                if (_outItem.dte > dts && ValidTeamNoneWorkTime(_outItem, noneworkdays))
                {
                    _outPuts.Add(_outItem);
                }
            }


            Dictionary<DateTime, int> weekDic = new Dictionary<DateTime, int>();
            foreach (var item in _outPuts)
            {
                if (!weekDic.ContainsKey(item.dts))
                {
                    weekDic.Add(item.dts, DateHelper.GetWeek(item.dts));
                }
                item.week = weekDic[item.dts];
            }



        }

        /// <summary>
        /// 获取系统中的放假时间
        /// </summary>
        /// <returns></returns>
        private List<NoneWorkDays> GetNoneWorkDays()
        {
            List<NoneWorkDays> ret = new List<NoneWorkDays>();
            var lst = sysDicRepository.GetAll().Where(x => x.DictKey == DictKey.长假设置).ToList();
            foreach (var item in lst)
            {
                //20170101-20170210
                string[] dd = item.DisplayName.Split(new char[] { '-', '-' }, StringSplitOptions.RemoveEmptyEntries);
                if (dd.Length == 2)
                {
                    IFormatProvider ifp = new CultureInfo("zh-CN", true);

                    DateTime dts = DateTime.ParseExact(dd[0], "yyyyMMdd", ifp);
                    DateTime dt2 = DateTime.ParseExact(dd[1], "yyyyMMdd", ifp);
                    if (dts < dt2)
                    {
                        ret.Add(new NoneWorkDays() { dts = dts, dte = dt2 });
                    }
                }
            }
            return ret;
        }

        /// <summary>
        /// 根据项目的状态，判断出什么时候该出周报
        /// </summary>
        /// <param name="projectIds"></param>
        /// <param name="wokingWeek"></param>
        private void _GetProjectDoingWeek(List<int> projectIds, List<ProjectWeek> wokingWeek)
        {
            List<ProjectWeek> __wokingWeek = new List<ProjectWeek>();
            int index = 1;
            var proProgresses = projectManager.projectProgressRepository.GetAll().Where(x => projectIds.Contains(x.ProjectId)).ToList();
            foreach (var pId in projectIds)
            {
                //从小到大的顺序，有了
                /*
                 * 2017-1-1>>进行中
                 * 2017-2-1>>暂停
                 * 2017-3-7>>完成
                 * 2017-3-7>>终止  
                 * 2017-3-7>>准备
                 */
                var reportTimes = proProgresses.Where(x => x.ProjectId == pId).Select(x => x.ReportTime).Distinct().OrderBy(x => x).ToList();

                if (reportTimes.Count > 0)
                {
                    var pre = proProgresses.Where(x => x.ProjectId == pId && x.ReportTime == reportTimes[0]).OrderByDescending(x => x.Id).FirstOrDefault();
                    if (reportTimes.Count > 1)
                    {
                        for (int i = 1; i < reportTimes.Count; i++)
                        {
                            var cur = proProgresses.Where(x => x.ProjectId == pId && x.ReportTime == reportTimes[i]).OrderByDescending(x => x.Id).FirstOrDefault();

                            if (pre.Status == Status.进行中)
                            {
                                __wokingWeek.Add(new ProjectWeek()
                                 {
                                     id = index,
                                     projectId = pId,
                                     reportWeek = pre.ReportWeek,
                                     dts = pre.ReportTime,
                                     dte = cur.ReportTime
                                 });
                                index++;
                                pre = cur;
                            }
                            else if (cur.Status == Status.进行中 && cur.ReportTime == reportTimes[reportTimes.Count - 1])
                            {
                                __wokingWeek.Add(new ProjectWeek()
                                {
                                    id = index,
                                    projectId = pId,
                                    reportWeek = cur.ReportWeek,
                                    dts = cur.ReportTime,
                                    dte = DateTime.Now
                                });
                                index++;
                            }
                        }
                    }
                    else
                    {
                        if (pre.Status == Status.进行中)
                        {
                            __wokingWeek.Add(new ProjectWeek()
                            {
                                id = index,
                                projectId = pId,
                                reportWeek = pre.ReportWeek,
                                dts = pre.ReportTime,
                                dte = DateTime.Now
                            });
                            index++;
                        }
                    }
                }
            }

            /*
             * 20170101--20170125单周报
             * 20170125--20170505单周报
             * 
             * 目的在于合并时间段
             */

            do
            {
                var tmp = __wokingWeek.OrderBy(t => t.dts).ToList();
                var t0 = tmp[0];
                if (tmp.Count > 1)
                {
                    var next = tmp.Where(x => x.projectId == t0.projectId && x.id != t0.id && x.reportWeek == t0.reportWeek).FirstOrDefault();
                    if (next != null && next.dts == t0.dte)
                    {
                        t0.dte = next.dte;
                        __wokingWeek.Remove(next);
                    }
                    else
                    {
                        __wokingWeek.Remove(t0);
                        wokingWeek.Add(t0);
                    }
                }
                else
                {
                    __wokingWeek.Remove(t0);
                    wokingWeek.Add(t0);
                }



            } while (__wokingWeek.Count > 0);


        }

        /// <summary>
        /// 非项目时间段，不需要提交周报
        /// </summary>
        /// <param name="work"></param>
        /// <param name="wokingWeek"></param>
        /// <returns></returns>
        private bool ValidTeamWorkTime(ProjectWeekTeam work, List<ProjectWeek> wokingWeek)
        {

            var lst = wokingWeek.Where(x => x.projectId == work.proId).ToList();
            foreach (var item in lst)
            {
                //item>>项目周期
                if (work.dte > item.dts && work.dte < item.dte)
                {
                    if (item.reportWeek == 2)
                    {
                        work.dte = work.dts.AddDays(14);
                    }

                    return true;
                }
                else if (work.dts >= item.dts && work.dts < item.dte)
                {
                    if (item.reportWeek == 2)
                    {
                        work.dte = work.dts.AddDays(14);
                    }
                    return true;
                }
                else if (work.dts <= item.dts && work.dte >= item.dte)
                {
                    if (item.reportWeek == 2)
                    {
                        work.dte = work.dts.AddDays(14);
                    }
                    return true;
                }
            }

            return false;
        }

        /// <summary>
        /// 休息时间，不需要提交周报
        /// </summary>
        /// <param name="work"></param>
        /// <param name="noneworkdays"></param>
        /// <returns></returns>
        private bool ValidTeamNoneWorkTime(ProjectWeekTeam work, List<NoneWorkDays> noneworkdays)
        {
            foreach (var item in noneworkdays)
            {
                if (work.dts >= item.dts && work.dte <= item.dte)
                {
                    return false;
                }
            }

            return true;
        }

        /// <summary>
        /// 移除团队成员
        /// </summary>
        /// <param name="projectRoleId">projectTeam表的主键Id</param>
        /// <returns></returns>
        public async Task RemoveProjectTeam(int projectRoleId, int projectId)
        {
            await projectManager.projectTeamRepository.DeleteAsync(projectRoleId);
            await operationLogManager.Create(projectId, "项目成员编辑", HostOperation.项目, Newtonsoft.Json.JsonConvert.SerializeObject(new { ProjectRoleId = projectRoleId, ProjectId = projectId }));
        }

        /// <summary>
        /// 离开项目组
        /// </summary>
        /// <param name="projectRoleId"></param>
        /// <param name="projectId"></param>
        /// <returns></returns>
        public async Task LeaveProjectTeam(int projectRoleId, int projectId)
        {
            var team = await projectManager.projectTeamRepository.GetAsync(projectRoleId);
            team.EndTime = DateTime.Now.Date;
            await projectManager.projectTeamRepository.UpdateAsync(team);
            await operationLogManager.Create(projectId, "项目成员编辑", HostOperation.项目, Newtonsoft.Json.JsonConvert.SerializeObject(new { ProjectRoleId = projectRoleId, ProjectId = projectId }));
        }

        /// <summary>
        /// 得到最新的项目进度
        /// </summary>
        /// <param name="projectId"></param>
        /// <returns></returns>
        public async Task<GetProgressOutPut> GetLastProgressOutPut(int projectId)
        {
            GetProgressOutPut outPut = new Dto.GetProgressOutPut();
            var _lastprogress = await projectManager.projectProgressRepository.GetAll().Where(x => x.ProjectId == projectId).OrderByDescending(x => x.ReportTime).FirstOrDefaultAsync();
            var project = await projectManager.projectRepository.GetAsync(projectId);
            if (_lastprogress != null)
            {
                var progress = await projectManager.projectProgressRepository.GetAll().Where(x => x.ProjectId == projectId && x.ReportTime == _lastprogress.ReportTime).OrderByDescending(x => x.Id).FirstOrDefaultAsync();


                outPut.Status = progress.Status.ToString();
                outPut.ProgressVal = (int)project.ProgressStatus;
                outPut.Progress = project.ProgressStatus.ToString();
                outPut.StatusVal = (int)progress.Status;
                outPut.Note = progress.Note;
                outPut.ReportWeek = progress.ReportWeek;
            }
            else
            {
                outPut.ReportWeek = project.ReportWeek;
            }

            outPut.ActualEndTime = project.PlanEndDate.ToString("yyyy-MM-dd");
            outPut.ReportTime = DateTime.Now.ToString("yyyy-MM-dd");
            return outPut;
        }

        /// <summary>
        /// 获取所有进度
        /// </summary>
        /// <param name="projectId"></param>
        /// <returns></returns>
        public List<GetProgressOutPut> GetProgressAll(int projectId)
        {
            var res = projectManager.projectProgressRepository.GetAll().Where(x => x.ProjectId == projectId).OrderByDescending(x => x.ReportTime).ToList().Select(x =>
                new GetProgressOutPut()
                {
                    Id = x.Id,
                    ActualEndTime = x.ActualEndTime.ToString("yyyy-MM-dd"),
                    Note = x.Note,
                    ReportTime = x.ReportTime.ToString("yyyy-MM-dd"),
                    Status = x.Status.ToString(),
                    ReportWeek = x.ReportWeek
                }).ToList();
            return res;
        }


        /// <summary>
        /// 成员评价
        /// </summary>
        public List<GetTeamCommentOutPut> GetTeamComment(int projectId)
        {
            List<GetTeamCommentOutPut> result = new List<GetTeamCommentOutPut>();
            //需要写成员评价的角色
            var manPlanRoles = projectManager.projectRoleInfoRepository.GetAll().Where(x => x.IsHumanWork).ToList();
            //需要写成员评价的团队成员
            var ids = manPlanRoles.Select(m => m.Id);
            var teams = projectManager.projectTeamRepository.GetAll().Where(x => ids.Contains(x.ProjectRoleId) && x.ProjectId == projectId).ToList();
            foreach (var t in teams)
            {
                var user = UserManager.Users.Where(x => x.Id == t.UserId).SingleOrDefault();
                var role = manPlanRoles.Where(x => x.Id == t.ProjectRoleId).SingleOrDefault();
                var comment = projectManager.teamCommentRepository.GetAll().Where(x => x.ProjectId == projectId && x.UserId == t.UserId && x.ProjectRoleId == t.ProjectRoleId).SingleOrDefault();
                var outPut = new GetTeamCommentOutPut()
                {
                    ProjectRoleId = t.ProjectRoleId,
                    UserId = t.UserId,
                    UserName = user.Surname + user.Name,
                    RoleName = role.RoleName,
                    Score = 1,
                    Content = string.Empty
                };
                if (comment != null)
                {
                    outPut.Id = comment.Id;
                    outPut.Score = comment.Score;
                    outPut.Content = comment.Content;
                }
                result.Add(outPut);
            }
            return result;
        }

        /// <summary>
        /// 编辑团队评价
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public Task UpdateTeamComment(List<EditTeamCommentInPut> input)
        {
            throw new NotImplementedException();
        }



        public List<GetOperationLogOutPut> GetOperationLog(GetOperationLogInPut input)
        {
            var userId = AbpSession.GetUserId();

            var model = new List<GetOperationLogOutPut>();
            switch (input.Operation)
            {
                case HostOperation.项目:
                    var all = operationLogManager.operationLogRepository.GetAll().Where(x => x.HostId == input.HostId && x.Operation == input.Operation).OrderByDescending(x => x.CreationTime);
                    model = all.MapTo<List<GetOperationLogOutPut>>();
                    break;
                case HostOperation.文档:
                    var docIds = projectManager.projectDocmeutRepository.GetAll().Where(x => x.ProjectId == input.HostId).ToList().Where(x => x.DocTypeId == 0 || permissionService.HasPermission(input.HostId, userId, x.DocTypeId, DocmentFunctions.文档日志查看)).Select(x => x.Id).ToList();
                    var all2 = operationLogManager.operationLogRepository.GetAll().Where(x => docIds.Contains(x.HostId) && x.Operation == input.Operation).OrderByDescending(x => x.CreationTime);
                    model = all2.MapTo<List<GetOperationLogOutPut>>();
                    break;
                default:
                    break;
            }


            foreach (var item in model)
            {
                var u = userManager.Users.Where(x => x.Id == item.CreatorUserId).SingleOrDefault();
                if (u != null)
                {
                    item.CreateionUser = u.Name;
                }

            }
            return model;
        }


        public List<GetProjectProgressOutPut> GetProjectProgress()
        {
            var userId = AbpSession.GetUserId();
            List<GetProjectProgressOutPut> results = new List<GetProjectProgressOutPut>();
            var alls = projectManager.projectRepository.GetAll().Where(x => x.Status == Status.进行中).ToList().Where(x => permissionService.HasPermission(userId, x.Id, ProjectFunctions.项目查看));
            foreach (var item in alls)
            {
                var progress = projectManager.projectProgressRepository.GetAll().Where(x => x.ProjectId == item.Id).OrderByDescending(x => x.Id).FirstOrDefault();
                var outPut = new GetProjectProgressOutPut()
                {
                    Id = item.Id,
                    ProductNo = item.ProductNo,
                    ProjectNo = item.ProjectNo,
                    PlanStartTime = item.PlanStartDate.ToString("yyyy-MM-dd"),
                    PlanEndTime = item.PlanEndDate.ToString("yyyy-MM-dd"),
                    ActualStartTime = item.ActualStartDate.ToString("yyyy-MM-dd"),
                    ActualEndTime = item.ActualEndDate.ToString("yyyy-MM-dd"),
                    ProjectName = item.ProjectName,
                    TaskType = item.TaskType.ToString(),
                    Status = item.Status.ToString(),
                    RdCenter = item.RdCenter,
                    Schedule = item.ProgressStatus.ToString(),
                    DelayPeriod = 0
                };

                var planDay = (item.PlanEndDate - item.PlanStartDate).Days;
                var delayDay = (DateTime.Now - item.ActualStartDate).Days;
                if (delayDay > planDay)
                {
                    outPut.DelayPeriod = delayDay - planDay;
                }
                results.Add(outPut);
            }
            return results;
        }


        public List<GetProjectProgressOutPut> GetFollowerProjects(GetProjectInPut input)
        {
            var userId = AbpSession.GetUserId();
            List<GetProjectProgressOutPut> results = new List<GetProjectProgressOutPut>();
            var alls = projectManager.projectRepository.GetAll()
                .Where(x => x.Customer.Equals(input.Customer)
                && x.CreationTime >= input.dts && x.CreationTime < input.dte
                && input.status.Contains((int)x.Status)
                ).ToList().Where(x => permissionService.HasPermission(userId, x.Id, ProjectFunctions.项目查看)).ToList();

            if (input.phaseStatus == 0)
            {
                var proIds = alls.Select(x => x.Id).ToList();
                var filterProIds = projectPhaseRepository.GetAll().Where(x => !x.IsDeleted && proIds.Contains(x.ProjectId) && input.phase.Contains(x.PhaseId)).Select(x => x.ProjectId).Distinct().ToList();
                alls = alls.Where(x => filterProIds.Contains(x.Id)).ToList();
            }
            else if (input.phaseStatus > 0)
            {
                var proIds = alls.Select(x => x.Id).ToList();
                var filterProIds = projectPhaseRepository.GetAll().Where(x => !x.IsDeleted && proIds.Contains(x.ProjectId) && input.phase.Contains(x.PhaseId) && x.IsFinsh).Select(x => x.ProjectId).Distinct().ToList();
                alls = alls.Where(x => filterProIds.Contains(x.Id)).ToList();

            }


            foreach (var item in alls)
            {
                //var lastProgress = GetLastProgressOutPut(item.Id);
                var outPut = new GetProjectProgressOutPut()
                {
                    Id = item.Id,
                    ProductNo = item.ProductNo,
                    ProjectNo = item.ProjectNo,
                    PlanStartTime = item.PlanStartDate.ToString("yyyy-MM-dd"),
                    PlanEndTime = item.PlanEndDate.ToString("yyyy-MM-dd"),
                    ActualStartTime = item.ActualStartDate.ToString("yyyy-MM-dd"),
                    ActualEndTime = item.ActualEndDate.ToString("yyyy-MM-dd"),
                    ProjectName = item.ProjectName,
                    TaskType = item.TaskType.ToString(),
                    Status = item.Status.ToString(),
                    RdCenter = item.RdCenter,
                    Schedule = item.ProgressStatus.ToString(),
                    DelayPeriod = 0
                };

                //var planDay = (item.PlanEndDate - item.PlanStartDate).Days;
                //var delayDay = (DateTime.Now - item.ActualStartDate).Days;
                //if (delayDay > planDay)
                //{
                //    outPut.DelayPeriod = delayDay - planDay;
                //}
                results.Add(outPut);
            }
            return results;
        }

        public List<dynamic> GetHistoryProInquiry(string customer)
        {
            int minProYear = projectManager.projectRepository.GetAll().Select(x => x.CreationTime.Year).Min();
            int minInquiryYear = inquiryRepository.GetAll().Select(x => x.CreateOn.Year).Min();

            int startyear = minProYear < minInquiryYear ? minProYear : minInquiryYear;
            int endYear = DateTime.Now.Year;
            List<dynamic> ret = new List<dynamic>();

            do
            {
                int proCount = projectManager.projectRepository.GetAll().Where(x => x.Customer == customer && x.CreationTime.Year == startyear).Count();
                int inquiryCount = inquiryRepository.GetAll().Where(x => x.CustomerName == customer && x.CreateOn.Year == startyear).Count();

                ret.Add(new { proCount = proCount, inquiryCount = inquiryCount, year = startyear });

                startyear++;
            } while (startyear <= endYear);

            return ret;
        }

        public List<ProjectOutPut> GetByProductId(int productId)
        {
            var userId = (long)AbpSession.UserId;
            var product = productRepository.Get(productId);
            var projects = projectManager.projectRepository.GetAll().Where(x => x.ProductNo == product.Code).ToList();
            var result = projects.MapTo<List<ProjectOutPut>>();
            bool permissionToViewCustomer = permissionService.HasSysPermission(userId, ProjectFunctions.客户查看);
            if (!permissionToViewCustomer)
            {
                foreach (var item in result)
                {
                    item.Customer = "******";
                }
            }
            return result;
        }


        public async Task<List<GetProjectTeamCheckedTreeDto>> GetProjectTeamTree(int projectId, int taskId)
        {
            var message = pushMessageRepository.GetAll().Where(x => x.ProjectId == projectId && x.TaskId == taskId).Select(x => x.UserId).ToList();

            List<GetProjectTeamCheckedTreeDto> tree = new List<GetProjectTeamCheckedTreeDto>();
            var teams = projectManager.projectTeamRepository.GetAll().Where(x => x.ProjectId == projectId).ToList();
            var groups = teams.GroupBy(x => x.ProjectRoleId).Select(x => x.Key);
            foreach (var projectRoleId in groups)
            {
                var role = await projectManager.projectRoleInfoRepository.GetAsync(projectRoleId);
                var id = Guid.NewGuid();
                var dto = new GetProjectTeamCheckedTreeDto()
                {
                    @checked = false,
                    children = new List<GetProjectTeamCheckedTreeDto>(),
                    expanded = true,
                    id = id.ToString(),
                    leaf = false,
                    parentId = "0",
                    text = role.RoleName
                };
                var userId = teams.Where(x => x.ProjectRoleId == projectRoleId).Select(x => x.UserId);
                var users = UserManager.Users.Where(x => userId.Contains(x.Id)).ToList();
                foreach (var item in users)
                {
                    var userDto = new GetProjectTeamCheckedTreeDto()
                    {
                        @checked = message.Any(x => x == item.Id),
                        children = new List<GetProjectTeamCheckedTreeDto>(),
                        expanded = true,
                        id = item.Id.ToString(),
                        leaf = true,
                        parentId = id.ToString(),
                        text = item.Name
                    };
                    dto.children.Add(userDto);
                }
                tree.Add(dto);
            }
            return tree.Where(x => x.parentId == "0").ToList();
        }

        /// <summary>
        /// 项目阶段
        /// </summary>
        public List<Admin.Dto.GetPhaseInfoTreeOutPut> GetProjectPhase(int projectId)
        {
            List<Admin.Dto.GetPhaseInfoTreeOutPut> result = new List<Admin.Dto.GetPhaseInfoTreeOutPut>();
            var phases = projectPhaseRepository.GetAll().OrderBy(x => x.Indexno).Where(x => !x.IsDeleted && x.ProjectId == projectId).ToList();
            foreach (var item in phases)
            {
                var phaseInfo = phaseInfoRepository.Get(item.PhaseId);
                var id = (item.Id * -1).ToString();
                var parent = new Admin.Dto.GetPhaseInfoTreeOutPut()
                {
                    id = id,
                    expanded = true,
                    isFinsh = item.IsFinsh,
                    leaf = false,
                    Indexno = item.Indexno,
                    note = item.Note,
                    PlanFinishDate = item.PlanFinishDate,
                    parentId = "0",
                    children = new List<Admin.Dto.GetPhaseInfoTreeOutPut>(),
                    text = phaseInfo.Name
                };
                var children = projectPhaseItemRepository.GetAll().OrderBy(x => x.Indexno).Where(x => x.PhaseId == item.PhaseId && x.ProjectId == projectId).ToList();
                foreach (var c in children)
                {
                    var phaseItem = phaseItemRepository.Get(c.PhaseItemId);
                    var child = new Admin.Dto.GetPhaseInfoTreeOutPut()
                    {
                        id = c.Id.ToString(),
                        expanded = true,
                        Indexno = c.Indexno,
                        isFinsh = c.IsFinsh,
                        leaf = true,
                        note = c.Note,
                        PlanFinishDate = c.PlanFinishDate,
                        parentId = id,
                        children = new List<Admin.Dto.GetPhaseInfoTreeOutPut>(),
                        text = phaseItem.Name
                    };
                    parent.children.Add(child);
                }
                result.Add(parent);
            }
            return result;
        }

        public int GetProjectPhaseCount(int projectId)
        {
            return projectPhaseRepository.GetAll().Where(x => x.ProjectId == projectId && !x.IsDeleted).Count() +
                  projectPhaseItemRepository.GetAll().Where(x => x.ProjectId == projectId && !x.IsDeleted).Count();
        }


        public dynamic GetHistoryProjectPhase()
        {

            List<string> exceptCustomer = new List<string>() { };
            var expectCustomer = sysDicRepository.GetAll().Where(x => x.DictKey == DictKey.排除客户列表).Select(x => x.DisplayName).ToList();





            var proLst = projectManager.projectRepository.GetAll().Where(x => !expectCustomer.Contains(x.Customer)).ToList();
            var proPhaseLst = projectPhaseRepository.GetAll().Where(x => !x.IsDeleted).ToList();
            var phaseLst = phaseInfoRepository.GetAll().Where(x => !x.IsDeleted).OrderBy(x => x.Indexno).ToList();

            var yearList = proLst.Select(x => x.CreationTime.Year).Distinct();
            List<dynamic> yearPhase = new List<dynamic>();
            foreach (var year in yearList)
            {
                var proIds = proLst.Where(x => x.CreationTime.Year == year).Select(x => x.Id).ToList();
                var group = proPhaseLst.Where(x => proIds.Contains(x.ProjectId)).GroupBy(x => x.PhaseId);
                foreach (var item in group)
                {
                    yearPhase.Add(new
                    {
                        year = year,
                        phaseId = item.Key,
                        proCount = item.Count(),
                        proFCount = item.Where(x => x.IsFinsh).Count()
                    });
                }
            }

            return new
            {
                yearPhase = yearPhase,
                phaseLst = phaseLst.Select(x => new
                {
                    x.Indexno,
                    x.Id,
                    x.Name
                })
            };

        }
        public int GetProjectPhaseFinishedCount(int projectId)
        {
            return projectPhaseRepository.GetAll().Where(x => x.ProjectId == projectId && !x.IsDeleted && x.IsFinsh).Count() +
               projectPhaseItemRepository.GetAll().Where(x => x.ProjectId == projectId && !x.IsDeleted && x.IsFinsh).Count();
        }

        public async Task SetProjectTaskNote(CreateProjectTaskNoteInput input)
        {
            var p = await projectManager.projectRepository.GetAsync(input.ProjectId);
            p.TaskNote = input.taskNote;
        }
        public async Task SetProjectPhase(List<EditProjectPhaseInPut> input)
        {
            int projectId = 0;
            foreach (var item in input)
            {


                if (item.Id > 0)
                {
                    var phaseItem = await projectPhaseItemRepository.GetAsync(item.Id);
                    phaseItem.IsFinsh = item.IsFinsh;
                    phaseItem.Note = item.Note;
                    phaseItem.PlanFinishDate = item.PlanFinishDate;
                    phaseItem.Indexno = item.Indexno;

                    await projectPhaseHistoryRepository.InsertAsync(new ProjectPhaseHistory()
                    {
                        IsFinsh = item.IsFinsh,
                        Note = item.Note,
                        PhaseId = 0,
                        PhaseItemId = item.Id,
                        PlanFinishDate = item.PlanFinishDate,
                        ProjectId = phaseItem.ProjectId
                    });

                    if (projectId == 0)
                    {
                        projectId = phaseItem.ProjectId;
                    }
                }
                else
                {
                    var phase = await projectPhaseRepository.GetAsync(item.Id * -1);
                    phase.IsFinsh = item.IsFinsh;
                    phase.Note = item.Note;
                    phase.Indexno = item.Indexno;
                    phase.PlanFinishDate = item.PlanFinishDate;

                    await projectPhaseHistoryRepository.InsertAsync(new ProjectPhaseHistory()
                    {
                        IsFinsh = item.IsFinsh,
                        Note = item.Note,
                        PlanFinishDate = item.PlanFinishDate,
                        PhaseId = item.Id * -1,
                        PhaseItemId = 0,
                        ProjectId = phase.ProjectId
                    });
                    if (projectId == 0)
                    {
                        projectId = phase.ProjectId;
                    }
                }
            }
            if (projectId > 0)
            {
                await operationLogManager.Create(projectId, "项目阶段进展编辑", HostOperation.项目, Newtonsoft.Json.JsonConvert.SerializeObject(input));
            }



        }

        public List<dynamic> GetProjectPhaseReport(int productId = 0)
        {
            var userId = AbpSession.GetUserId();
            List<dynamic> result = new List<dynamic>();
            var alls = new List<ProjectInfo>();
            if (productId == 0)
            {
                alls = projectManager.projectRepository.GetAll().Where(x => x.Status == Status.进行中).OrderBy(x => x.Customer).ToList()
                .Where(x => permissionService.HasPermission(userId, x.Id, ProjectFunctions.项目查看)).ToList();
            }
            else
            {
                var product = productRepository.Get(productId);
                alls = projectManager.projectRepository.GetAll().Where(x => x.ProductNo == product.Code).OrderBy(x => x.Customer).ToList()
                .Where(x => permissionService.HasPermission(userId, x.Id, ProjectFunctions.项目查看)).ToList();
            }


            bool permissionToViewCustomer = permissionService.HasSysPermission(userId, ProjectFunctions.客户查看);

            foreach (var item in alls)
            {
                var product = productRepository.GetAll().Where(x => x.Code == item.ProductNo).FirstOrDefault();
                dynamic dy = new ExpandoObject();
                dy.projectId = item.Id;
                dy.Customer = permissionToViewCustomer ? item.Customer : "******";
                dy.projectName = item.ProjectName;
                dy.projectStart = item.ActualStartDate.ToString("yyyy-MM-dd");
                dy.projectNo = item.ProjectNo;
                dy.productNo = item.ProductNo;
                dy.productId = product == null ? 0 : product.Id;

                var phase = projectPhaseRepository.GetAll().Where(x => !x.IsDeleted && x.ProjectId == item.Id).ToList();
                foreach (var p in phase)
                {
                    var f = phaseInfoRepository.Get(p.PhaseId);
                    ((IDictionary<string, object>)dy).Add(f.Name, p.Note);
                    ((IDictionary<string, object>)dy).Add(f.Name + "IsFinsh", p.IsFinsh);
                }
                var phaseItems = projectPhaseItemRepository.GetAll().Where(x => x.ProjectId == item.Id).ToList();
                foreach (var t in phaseItems)
                {
                    var c = phaseItemRepository.Get(t.PhaseItemId);
                    ((IDictionary<string, object>)dy).Add(c.Name, t.Note);
                    ((IDictionary<string, object>)dy).Add(c.Name + "IsFinsh", t.IsFinsh);
                }
                result.Add(dy);
            }
            return result;
        }


        public async Task<List<dynamic>> GetProjectDocumentReport(int productId = 0)
        {
            var userId = AbpSession.GetUserId();
            bool permissionToViewCustomer = permissionService.HasSysPermission(userId, ProjectFunctions.客户查看);

            List<dynamic> result = new List<dynamic>();
            var alls = new List<ProjectInfo>();
            if (productId == 0)
            {
                alls = await projectManager.projectRepository.GetAll().Where(x => x.Status == Status.进行中).OrderBy(x => x.Customer).ToListAsync();
            }
            else
            {
                var product = productRepository.Get(productId);
                alls = projectManager.projectRepository.GetAll().Where(x => x.ProductNo == product.Code).OrderBy(x => x.Customer).ToList();
            }

            alls = alls.Where(x => permissionService.HasPermission(userId, x.Id, ProjectFunctions.项目查看)).ToList();

            foreach (var item in alls)
            {
                dynamic dy = new ExpandoObject();
                dy.projectId = item.Id;
                dy.Customer = permissionToViewCustomer ? item.Customer : "******";
                dy.projectName = item.ProjectName;
                dy.projectNo = item.ProjectNo;
                dy.productNo = item.ProductNo;
                var docs = projectManager.projectDocmeutRepository.GetAll().Where(x => x.ProjectId == item.Id).ToList();
                var docTypes = projectManager.projectDocTypeRepository.GetAll().Where(x => x.ProjectId == item.Id).ToList();
                foreach (var dt in docTypes)
                {
                    var type = documentTypeRepository.Get(dt.DocTypeId);
                    ((IDictionary<string, object>)dy).Add(type.Name + type.Id, docs.Count(x => x.DocTypeId == dt.DocTypeId) + "/" + dt.UploadNum);
                }
                result.Add(dy);
            }
            return result;
        }

        public void GetMailRecord(int recordId)
        {
            string mail_account = System.Configuration.ConfigurationManager.AppSettings["mail_account"];
            string mail_pwd = System.Configuration.ConfigurationManager.AppSettings["mail_pwd"];
            string mail_group = System.Configuration.ConfigurationManager.AppSettings["mail_group"];
            string mail_server = System.Configuration.ConfigurationManager.AppSettings["mail_server"];
            string mail_email = System.Configuration.ConfigurationManager.AppSettings["mail_email"];
            string mail_accountdisplay = System.Configuration.ConfigurationManager.AppSettings["mail_accountdisplay"];

            var record = mailManagerRepository._mailRecordRepository.Get(recordId);
            List<string> tos = record.Receivers.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();


            try
            {
                mailManagerRepository.SendMail(mail_server, mail_account, mail_pwd, mail_group, mail_email, mail_accountdisplay, tos, record.Subject, record.Body);
                record.IsSend = true;
                record.IsSuccess = true;
            }
            catch (Exception ex)
            {

                record.IsSend = true;
                record.IsSuccess = false;
                record.ErrorMsg = ex.Message;
            }
            mailManagerRepository._mailRecordRepository.Update(record);
        }


        public List<GetProjectPhaseCheckTree> GetProjectPhaseCheckTree(int projectId = 0)
        {
            List<Dto.GetProjectPhaseCheckTree> outPut = new List<Dto.GetProjectPhaseCheckTree>();
            var phases = phaseInfoRepository.GetAll().OrderBy(x => x.Indexno).ToList();
            var child = phaseItemRepository.GetAll().OrderBy(x => x.Indexno).ToList();

            var phaseIds = projectPhaseRepository.GetAll().Where(x => !x.IsDeleted && x.ProjectId == projectId).Select(x => x.PhaseId).ToList();
            var phaseItems = projectPhaseItemRepository.GetAll().Where(x => x.ProjectId == projectId).Select(x => x.PhaseItemId).ToList();

            foreach (var item in phases)
            {
                var id = (item.Id * -1).ToString();
                var parent = new Dto.GetProjectPhaseCheckTree()
                {
                    id = id,
                    leaf = !child.Any(m => m.PhaseId == item.Id),
                    expanded = true,
                    parentId = "0",
                    text = item.Name,
                    @checked = phaseIds.Contains(item.Id),
                    children = new List<Dto.GetProjectPhaseCheckTree>()
                };
                var children = child.Where(x => x.PhaseId == item.Id).OrderBy(x => x.Indexno);
                foreach (var c in children)
                {
                    var p = new Dto.GetProjectPhaseCheckTree()
                    {
                        id = c.Id.ToString(),
                        leaf = true,
                        @checked = phaseItems.Contains(c.Id),
                        expanded = true,
                        parentId = id,
                        text = c.Name,
                        children = new List<Dto.GetProjectPhaseCheckTree>()
                    };
                    parent.children.Add(p);
                }
                outPut.Add(parent);
            }
            return outPut;
        }


        //public async Task<List<ProjectTeamOutPut>> GetProjectRole(int projectId)
        //{
        //    if (projectId == 0)
        //        throw new Abp.UI.UserFriendlyException("系统提示", "projectId不能为零");

        //    List<ProjectTeamOutPut> outPuts = new List<ProjectTeamOutPut>();
        //    var roles = projectManager.projectTeamRepository.GetAll().Where(x => x.ProjectId == projectId).Select(x => x.ProjectRoleId).ToList();

        //    foreach (var roleId in roles)
        //    {
        //        var role =await  projectManager.projectRoleInfoRepository.GetAsync(roleId);

        //        outPuts.Add(new ProjectTeamOutPut()
        //        {
        //            RoleName = role.RoleName,
        //            ProjectRoleId = role.Id
        //        });
        //    }
        //    return outPuts;
        //}

        public async Task FollowerProject(int projectId)
        {
            var userId = AbpSession.GetUserId();
            if (!permissionService.HasFollowedProject(userId, projectId))
            {
                await projectFollowerRepository.InsertAsync(new ProjectFollower()
                {
                    ProjectId = projectId,
                    UserId = userId
                });
            }
        }


        public async Task UnFollowerProject(int projectId)
        {

            var userId = AbpSession.GetUserId();
            if (permissionService.HasFollowedProject(userId, projectId))
            {
                ProjectFollower
                    f = await projectFollowerRepository.GetAll().Where(x => x.IsDeleted == false && x.UserId == userId && x.ProjectId == projectId).FirstOrDefaultAsync();

                await projectFollowerRepository.DeleteAsync(f.Id);
            }
        }

    }
}
